using System;
using System.Collections.Generic;
using System.Text;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel;
using System.Collections;
using System.Web.UI;
using System.Web.UI.HtmlControls;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WorkflowActions;

using Nintex.Workflow;
using Nintex.Workflow.Activities.Adapters;
using net.Windward.WorkflowActions;

namespace net.Windward.NWAdapters
{
    /// <summary>
    /// A Nintex Workflow action adapter for the RunReportActivity.
    /// </summary>
    public class RunReportNWActionAdapter : GenericRenderingAdapter
    {
        const string ReportDefinitionProperty = "ReportDefinition";
        const string SaveInSiteUrlProperty = "SaveInSiteUrl";
        const string SaveInDocLibUrlProperty = "SaveInDocLibUrl";
        const string ParameterXmlProperty = "ParameterXml";
        const string RunForQueryProperty = "RunForQuery";
        const string RunForConnStrProperty = "RunForConnStr";
        const string RunForAdapterProperty = "RunForAdapter";
        const string RunForEmailProperty = "RunForEmail";
        const string IsMapEmailColProperty = "IsMapEmailCol";
        const string OutputFormatProperty = "OutputFormat";
        const string MailServerProperty = "MailServer";
        const string MailFromProperty = "MailFrom";
        const string MailSubjectProperty = "MailSubject";
        const string MailBodyProperty = "MailBody";

        /// <summary>
        /// Gets the default action configuration.
        /// </summary>
        /// <param name="listId"></param>
        /// <returns></returns>
        public override NWActionConfig GetDefaultConfig(Guid listId)
        {
            NWActionConfig c = new NWActionConfig(this);

            // Build default parameters for the action. Create an array of ActivityParameters 
            // to represent each parameter and assign default values.
            c.Parameters = new ActivityParameter[14];

            // Report definition url parameter
            c.Parameters[0] = new ActivityParameter();
            c.Parameters[0].Name = ReportDefinitionProperty;
            c.Parameters[0].PrimitiveValue = new PrimitiveValue();
            c.Parameters[0].PrimitiveValue.Value = string.Empty;
            c.Parameters[0].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[1] = new ActivityParameter();
            c.Parameters[1].Name = SaveInSiteUrlProperty;
            c.Parameters[1].PrimitiveValue = new PrimitiveValue();
            c.Parameters[1].PrimitiveValue.Value = string.Empty;
            c.Parameters[1].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[2] = new ActivityParameter();
            c.Parameters[2].Name = SaveInDocLibUrlProperty;
            c.Parameters[2].PrimitiveValue = new PrimitiveValue();
            c.Parameters[2].PrimitiveValue.Value = string.Empty;
            c.Parameters[2].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[3] = new ActivityParameter();
            c.Parameters[3].Name = RunForQueryProperty;
            c.Parameters[3].PrimitiveValue = new PrimitiveValue();
            c.Parameters[3].PrimitiveValue.Value = string.Empty;
            c.Parameters[3].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[4] = new ActivityParameter();
            c.Parameters[4].Name = ParameterXmlProperty;
            c.Parameters[4].PrimitiveValue = new PrimitiveValue();
            c.Parameters[4].PrimitiveValue.Value = string.Empty;
            c.Parameters[4].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[5] = new ActivityParameter();
            c.Parameters[5].Name = RunForConnStrProperty;
            c.Parameters[5].PrimitiveValue = new PrimitiveValue();
            c.Parameters[5].PrimitiveValue.Value = string.Empty;
            c.Parameters[5].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[6] = new ActivityParameter();
            c.Parameters[6].Name = RunForAdapterProperty;
            c.Parameters[6].PrimitiveValue = new PrimitiveValue();
            c.Parameters[6].PrimitiveValue.Value = string.Empty;
            c.Parameters[6].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[7] = new ActivityParameter();
            c.Parameters[7].Name = RunForEmailProperty;
            c.Parameters[7].PrimitiveValue = new PrimitiveValue();
            c.Parameters[7].PrimitiveValue.Value = string.Empty;
            c.Parameters[7].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[8] = new ActivityParameter();
            c.Parameters[8].Name = IsMapEmailColProperty;
            c.Parameters[8].PrimitiveValue = new PrimitiveValue();
            c.Parameters[8].PrimitiveValue.Value = string.Empty;
            c.Parameters[8].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[9] = new ActivityParameter();
            c.Parameters[9].Name = OutputFormatProperty;
            c.Parameters[9].PrimitiveValue = new PrimitiveValue();
            c.Parameters[9].PrimitiveValue.Value = string.Empty;
            c.Parameters[9].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[10] = new ActivityParameter();
            c.Parameters[10].Name = MailServerProperty;
            c.Parameters[10].PrimitiveValue = new PrimitiveValue();
            c.Parameters[10].PrimitiveValue.Value = string.Empty;
            c.Parameters[10].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[11] = new ActivityParameter();
            c.Parameters[11].Name = MailFromProperty;
            c.Parameters[11].PrimitiveValue = new PrimitiveValue();
            c.Parameters[11].PrimitiveValue.Value = string.Empty;
            c.Parameters[11].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[12] = new ActivityParameter();
            c.Parameters[12].Name = MailSubjectProperty;
            c.Parameters[12].PrimitiveValue = new PrimitiveValue();
            c.Parameters[12].PrimitiveValue.Value = string.Empty;
            c.Parameters[12].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.Parameters[13] = new ActivityParameter();
            c.Parameters[13].Name = MailBodyProperty;
            c.Parameters[13].PrimitiveValue = new PrimitiveValue();
            c.Parameters[13].PrimitiveValue.Value = string.Empty;
            c.Parameters[13].PrimitiveValue.ValueType = SPFieldType.Text.ToString();

            c.TLabel = ActivityReferenceCollection.FindByAdapter(this).Name;
            c.IsValid = false;
            return c;
        }

        /// <summary>
        /// Validates the configuration, returning true for valid configurations, and false otherwise.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool ValidateConfig(ActivityContext context)
        {
            bool isValid = true;

            // Add logic to validate the configuration here
            Dictionary<string, ActivityParameterHelper> parameters = context.Configuration.GetParameterHelpers();
            
            // validate report definition url
            if (!parameters[ReportDefinitionProperty].Validate(typeof(string), context))
            {
                isValid &= false;
                validationSummary.AddError("Report Definition URL", ValidationSummaryErrorType.CannotBeBlank);
            }

            // validate save-in site url
            if (!parameters[SaveInSiteUrlProperty].Validate(typeof(string), context))
            {
                isValid &= false;
                validationSummary.AddError("Save-In Site URL", ValidationSummaryErrorType.CannotBeBlank);
            }

            // validate save-in document library url
            if (!parameters[SaveInDocLibUrlProperty].Validate(typeof(string), context))
            {
                isValid &= false;
                validationSummary.AddError("Save-In Document Library URL", ValidationSummaryErrorType.CannotBeBlank);
            }

            //bugbug: not implemented
            // validate parameter xml

            //bugbug: not implemented
            // validate run-for query

            //bugbug: not implemented
            // validate run-for conn str

            //bugbug: not implemented
            // validate run-for adapter

            //bugbug: not implemented
            // validate run-for email

            //bugbug: not implemented
            // validate IsMapEmailCol

            //bugbug: not implemented
            // validate output format

            //bugbug: not implemented
            // validate mail server

            //bugbug: not implemented
            // validate mail from

            //bugbug: not implemented
            // validate mail subject

            //bugbug: not implemented
            // validate mail body

            return isValid;
        }

        /// <summary>
        /// Gets the last saved configuration of the action.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="supportingActivities"></param>
        /// <param name="ruleConfigs"></param>
        /// <param name="listId"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public override NWActionConfig GetConfig(Activity a, List<Activity> supportingActivities, Hashtable ruleConfigs, Guid listId, WorkflowVariableCollection variables)
        {
            NWActionConfig c = this.GetDefaultConfig(listId);

            // Read the properties from Activity 'a' and update the values in the NWActionConfig.
            Dictionary<string, ActivityParameterHelper> parameters = c.GetParameterHelpers();

            // retrieve report definition url
            parameters[ReportDefinitionProperty].RetrieveValue(a, RunReportActivity.ReportDefinitionProperty, listId, variables);

            // retrieve save-in site url
            parameters[SaveInSiteUrlProperty].RetrieveValue(a, RunReportActivity.SaveInSiteUrlProperty, listId, variables);

            // retrieve save-in doc lib url
            parameters[SaveInDocLibUrlProperty].RetrieveValue(a, RunReportActivity.SaveInDocLibUrlProperty, listId, variables);

            // retrieve run-for query
            parameters[RunForQueryProperty].RetrieveValue(a, RunReportActivity.RunForQueryProperty, listId, variables);

            // retrieve parameter xml
            parameters[ParameterXmlProperty].RetrieveValue(a, RunReportActivity.ParameterXmlProperty, listId, variables);

            // retrieve run-for conn str
            parameters[RunForConnStrProperty].RetrieveValue(a, RunReportActivity.RunForConnStrProperty, listId, variables);

            // retrieve run-for adapter
            parameters[RunForAdapterProperty].RetrieveValue(a, RunReportActivity.RunForAdapterProperty, listId, variables);

            // retrieve run-for email
            parameters[RunForEmailProperty].RetrieveValue(a, RunReportActivity.RunForEmailProperty, listId, variables);

            // retrieve IsMapEmailCol
            parameters[IsMapEmailColProperty].RetrieveValue(a, RunReportActivity.IsMapEmailColProperty, listId, variables);

            // retrieve output format
            parameters[OutputFormatProperty].RetrieveValue(a, RunReportActivity.OutputFormatProperty, listId, variables);

            // retrieve mail server
            parameters[MailServerProperty].RetrieveValue(a, RunReportActivity.MailServerProperty, listId, variables);

            // retrieve mail server
            parameters[MailFromProperty].RetrieveValue(a, RunReportActivity.MailFromProperty, listId, variables);

            // retrieve mail server
            parameters[MailSubjectProperty].RetrieveValue(a, RunReportActivity.MailSubjectProperty, listId, variables);

            // retrieve mail server
            parameters[MailBodyProperty].RetrieveValue(a, RunReportActivity.MailBodyProperty, listId, variables);

            ActivityFlags f = ActivityFlags.GetFlags(a);
            c.SetLabels(f);

            c.IsValid = ValidateConfig(new ActivityContext(listId, ActivityReferenceCollection.FindByAdapter(this), c));
            return c;
        }

        /// <summary>
        /// Generates a WF Activity from the specified configuration.  This is called once for each action, 
        /// each time a user publishes a workflow.
        /// </summary>
        /// <param name="config"></param>
        /// <param name="parentWorkflow"></param>
        /// <param name="parentActivity"></param>
        /// <param name="condition"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public override CompositeActivity AddActivityToWorkflow(NWActionConfig config, RootWorkflowActivityWithData parentWorkflow, CompositeActivity parentActivity, RuleConditionReference condition, WorkflowVariableCollection variables)
        {
            // Create an instance of the Activity and set its properties based on config. Add it to the parent activity.
            RunReportActivity runReportActivity = new RunReportActivity();

            // assign parameter values
            Dictionary<string, ActivityParameterHelper> parameters = config.GetParameterHelpers();

            // assign report definition url
            parameters[ReportDefinitionProperty].AssignTo(runReportActivity, RunReportActivity.ReportDefinitionProperty, 
                parentWorkflow, parentActivity, variables);

            // assign save-in site url
            parameters[SaveInSiteUrlProperty].AssignTo(runReportActivity, RunReportActivity.SaveInSiteUrlProperty,
                parentWorkflow, parentActivity, variables);

            // assign save-in doc lib url
            parameters[SaveInDocLibUrlProperty].AssignTo(runReportActivity, RunReportActivity.SaveInDocLibUrlProperty,
                parentWorkflow, parentActivity, variables);

            // assign run-for query
            parameters[RunForQueryProperty].AssignTo(runReportActivity, RunReportActivity.RunForQueryProperty,
                parentWorkflow, parentActivity, variables);

            // assign parameter xml
            parameters[ParameterXmlProperty].AssignTo(runReportActivity, RunReportActivity.ParameterXmlProperty,
                parentWorkflow, parentActivity, variables);

            // assign run-for conn str
            parameters[RunForConnStrProperty].AssignTo(runReportActivity, RunReportActivity.RunForConnStrProperty,
                parentWorkflow, parentActivity, variables);

            // assign run-for adapter
            parameters[RunForAdapterProperty].AssignTo(runReportActivity, RunReportActivity.RunForAdapterProperty,
                parentWorkflow, parentActivity, variables);

            // assign run-for email
            parameters[RunForEmailProperty].AssignTo(runReportActivity, RunReportActivity.RunForEmailProperty,
                parentWorkflow, parentActivity, variables);

            // assign IsMapEmailCol
            parameters[IsMapEmailColProperty].AssignTo(runReportActivity, RunReportActivity.IsMapEmailColProperty,
                parentWorkflow, parentActivity, variables);

            // assign output format
            parameters[OutputFormatProperty].AssignTo(runReportActivity, RunReportActivity.OutputFormatProperty,
                parentWorkflow, parentActivity, variables);

            // assign mail server
            parameters[MailServerProperty].AssignTo(runReportActivity, RunReportActivity.MailServerProperty,
                parentWorkflow, parentActivity, variables);

            // assign mail server
            parameters[MailFromProperty].AssignTo(runReportActivity, RunReportActivity.MailFromProperty,
                parentWorkflow, parentActivity, variables);

            // assign mail server
            parameters[MailSubjectProperty].AssignTo(runReportActivity, RunReportActivity.MailSubjectProperty,
                parentWorkflow, parentActivity, variables);

            // assign mail server
            parameters[MailBodyProperty].AssignTo(runReportActivity, RunReportActivity.MailBodyProperty,
                parentWorkflow, parentActivity, variables);

            ActivityFlags f = new ActivityFlags();
            f.AddLabelsFromConfig(config);
            f.AssignTo(runReportActivity);

            parentActivity.Activities.Add(runReportActivity);
            return null;
        }

        public override ActionSummary BuildSummary(ActivityContext context)
        {
            // Construct an ActionSummary class to display details about this action
            return new ActionSummary("Runs Windward Reports.");
        }

        public override ActionSummary BuildRuntimeSummary(ActivityRuntimeContext context)
        {
            return base.BuildRuntimeSummary(context);
        }
    }
}